package com.open.capacity.finance.service.impl;

import com.open.capacity.commons.Result;
import com.open.capacity.finance.constant.AuditWarnStatus;
import com.open.capacity.finance.dao.AuditModelWarnPlanDetailDao;
import com.open.capacity.finance.dto.AuditModelBaseResult;
import com.open.capacity.finance.entity.AuditModel;
import com.open.capacity.finance.entity.AuditModelWarn;
import com.open.capacity.finance.entity.AuditModelWarnPlanDetail;
import com.open.capacity.finance.service.AbstractAuditMakeResultFactory;
import com.open.capacity.finance.service.AuditModelService;
import com.open.capacity.finance.service.AuditModelWarnService;
import com.open.capacity.finance.util.uuid.UUIDUtils;
import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.model.system.SysUser;
import com.open.capacity.user.model.SysCompany;
import com.open.capacity.user.service.SysCompanyService;
import com.open.capacity.utils.SysUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.open.capacity.commons.PageResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.open.capacity.commons.CodeEnum;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections4.MapUtils;

import com.open.capacity.finance.entity.AuditModelWarnPlan;
import com.open.capacity.finance.dao.AuditModelWarnPlanDao;
import com.open.capacity.finance.service.AuditModelWarnPlanService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

@Slf4j
@Service
public class AuditModelWarnPlanServiceImpl implements AuditModelWarnPlanService {

    @Autowired
    private AuditModelWarnPlanDao auditModelWarnPlanDao;
    @Autowired
    private AuditModelWarnPlanDetailDao detailDao;

    @Autowired
    private AuditModelService modelService;

    @Autowired
    private AuditModelWarnService warnService;

    @Autowired
    private SysCompanyService companyService;

    @Autowired
    private ApplicationContext context;

    /**
     * 添加
     *
     * @param auditModelWarnPlan
     */
    @Transactional
    public int save(AuditModelWarnPlan auditModelWarnPlan) {
        auditModelWarnPlan.setId(UUIDUtils.getOriginalUUIDWithoutBar());
        auditModelWarnPlan.setCreateTime(new Date());
        auditModelWarnPlan.setStatus(1);
        auditModelWarnPlan.setExcuteResult(0);
        for (AuditModelWarnPlanDetail detail : auditModelWarnPlan.getDetailList()) {
            detail.setPlanId(auditModelWarnPlan.getId());
            detailDao.save(detail);
        }

        return auditModelWarnPlanDao.save(auditModelWarnPlan);
    }

    /**
     * 修改
     *
     * @param auditModelWarnPlan
     */
    @Transactional
    public int update(AuditModelWarnPlan auditModelWarnPlan) {
        detailDao.deleteByPlanId(auditModelWarnPlan.getId());
        for (AuditModelWarnPlanDetail detail : auditModelWarnPlan.getDetailList()) {
            detail.setPlanId(auditModelWarnPlan.getId());
            detailDao.save(detail);
        }
        return auditModelWarnPlanDao.update(auditModelWarnPlan);
    }


    /**
     * 删除
     *
     * @param id
     */
    @Transactional
    public int delete(String id) {
        detailDao.deleteByPlanId(id);
        return auditModelWarnPlanDao.delete(id);
    }

    @Override
    @Transactional
    public int analyse(String keyValue, Map<String, Object> params) {
        Assert.isTrue(StringUtils.isNotEmpty(keyValue), "请选择需要执行分析的计划");
        SysUser loginUser = SysUserUtil.getLoginAppUser();

        AuditModelWarnPlan plan = findById(keyValue);

        List<SysCompany> companyList = companyService.findCompanys(new HashMap<>());

        for (SysCompany company : companyList) {
            try {
                for (AuditModelWarnPlanDetail detail : plan.getDetailList()) {
                    Map<String, Object> param = new HashMap<>();
                    param.put("companyId", company.getId());
                    param.put("modelId", detail.getModelId());
                    AuditModel model = modelService.findById(detail.getModelId());
                    param.put("kjnd", model.getDefaultKjnd());

                    try {

                        AuditModelBaseResult result = modelService.previewResult(param);
                        detail.setResultUrl(result.getResultFileUrl());
                        detail.setResultMd5(result.getResultFileMd5());
                        detailDao.update(detail);

                        if (result.getExists().equals(1)) {
                            AuditModelWarn lastWarn = warnService.findLastByModelId(detail.getModelId(), company.getId(), keyValue);
                            //忽略结果集相同的告警
                            if (lastWarn == null || !result.getResultFileMd5().equals(lastWarn.getResultMd5())) {
                                AuditModelWarn warn = new AuditModelWarn();
                                warn.setModelId(detail.getModelId());
                                warn.setModelName(model.getCode() + " " + model.getName());
                                warn.setWarnLevel(result.getExists());
                                warn.setResultMd5(result.getResultFileMd5());
                                warn.setResultUrl(result.getResultFileUrl());
                                warn.setDealFlag(0);
                                warn.setCreateTime(new Date());
                                warn.setCompanyId(company.getId());
                                warn.setPlanId(keyValue);
                                warn.setStatus(AuditWarnStatus.NEW.getCode());
                                warnService.save(warn);
                            }
                        }
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                }
                plan.setExcuteResult(1);
            } catch (Exception e) {
                log.error(e.getMessage());
                plan.setExcuteResult(-1);
            }
        }
        plan.setCreateUsername(loginUser.getRealName());
        plan.setCreateTime(new Date());
        auditModelWarnPlanDao.update(plan);

        //modelService.analyseModel(plan.getDetailList().stream().map(AuditModelWarnPlanDetail::getModelId).collect(Collectors.toList()), plan.getCompanyId(), param);

        return 1;
    }

    /**
     * 查询记录
     *
     * @param id
     * @return
     */
    public AuditModelWarnPlan findById(String id) {
        AuditModelWarnPlan model = auditModelWarnPlanDao.findById(id);
        model.setDetailList(detailDao.findByPlanId(id));
        return model;
    }

    /**
     * 分页
     *
     * @param params
     * @return
     */
    public PageResult<AuditModelWarnPlan> pageAll(Map<String, Object> params) {
        //设置分页信息，分别是当前页数和每页显示的总记录数【记住：必须在mapper接口中的方法执行之前设置该分页信息】
        if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null)
            PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);

        List<AuditModelWarnPlan> list = auditModelWarnPlanDao.findAll(params);
        PageInfo<AuditModelWarnPlan> pageInfo = new PageInfo(list);

        return PageResult.<AuditModelWarnPlan>builder().data(pageInfo.getList()).resp_code(CodeEnum.SUCCESS.getCode()).count(pageInfo.getTotal()).build();
    }

    /**
     * 列表
     *
     * @param params
     * @return
     */
    public List<AuditModelWarnPlan> findAll(Map<String, Object> params) {
        return auditModelWarnPlanDao.findAll(params);
    }

}
